/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.rpc.table;

import com.je.common.base.DynaBean;
import com.je.common.base.exception.APIWarnException;
import com.je.common.base.service.MetaService;
import com.je.common.base.table.BuildingSqlFactory;
import com.je.common.base.util.StringUtil;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.cache.table.DynaCache;
import com.je.meta.cache.table.TableCache;
import com.je.meta.service.table.MetaTableColumnService;
import com.je.meta.service.table.MetaTableIndexService;
import com.je.meta.service.table.MetaTableKeyService;
import com.je.meta.service.table.MetaTableTraceService;
import org.apache.servicecomb.provider.pojo.RpcSchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.UncategorizedSQLException;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @program: jecloud-meta
 * @author: LIULJ
 * @create: 2021-09-18 13:07
 * @description:
 */
@RpcSchema(schemaId = "metaTableColumnRpcService")
public class MetaTableColumnRpcServiceImpl implements MetaTableColumnRpcService {

    @Autowired
    private MetaTableColumnService metaTableColumnService;
    @Autowired
    private MetaService metaService;
    @Autowired
    private MetaTableKeyService metaTableKeyService;
    @Autowired
    private MetaTableIndexService metaTableIndexService;
    @Autowired
    private DynaCache dynaCache;
    @Autowired
    private TableCache tableCache;
    @Autowired
    private MetaTableTraceService metaTableTraceService;

    @Override
    public String checkColumnBelongtoView(String resourceId, String columnCode) {
        return metaTableColumnService.checkColumnBelongtoView(resourceId,columnCode);
    }

    @Override
    public String checkTypeById(String ids){
        return metaTableColumnService.checkTypeById(ids);
    }

    @Override
    public String removeColumnWithDll(DynaBean dynaBean, String ids) {
        StringBuffer sb = new StringBuffer();
        String tableCode = dynaBean.getStr("TABLECOLUMN_TABLECODE");
        //删除字段
        List<DynaBean> columns = metaService.select(ConditionsWrapper.builder().table("JE_CORE_TABLECOLUMN").in("JE_CORE_TABLECOLUMN_ID", ids.split(",")));
        //级联删除key键
        List<DynaBean> keys = getDelKeys(columns);
        String delKeyddl = deleteKey(tableCode, keys) + ";";
        if (!delKeyddl.equals(";")) {
            sb.append(delKeyddl);
        }
        //删除字段
        List<String> delSqls = BuildingSqlFactory.build().getDeleteColumnSql(tableCode, columns);
        for (String delSql : delSqls) {
            if (StringUtil.isNotEmpty(delSql)) {
                sb.append(delSql + ";");
            }
        }
        List<DynaBean> indexs = getDelIndexs(columns);
        deleteIndex(tableCode, indexs);
        deleteColumnMeta(tableCode, columns);
        tableCache.removeCache(tableCode);
        dynaCache.removeCache(tableCode);

        return sb.toString().replaceAll("\n","");
    }

    public String deleteKey(String tableCode, List<DynaBean> keys) throws UncategorizedSQLException {
        if(keys.size()==0){
            return "";
        }
        //删除表字段
        String delSql = BuildingSqlFactory.build().getDeleteKeySql(tableCode, keys);
        //删除键元数据
        metaTableKeyService.deleteKeyMeta(tableCode,keys);
        return delSql;
    }

    @Override
    public String deleteIndex(String tableCode, List<DynaBean> indexs) {
        if(indexs.size()==0){
            return "";
        }
        //删除元数据
        deleteIndexMeta(indexs);
        //删除物理索引
        String delSql = BuildingSqlFactory.build().getDeleteIndexSql(tableCode, indexs);
        return delSql;
    }

    @Override
    public boolean checkIsExistForeignKeyByColumnIds(String ids) {
        return metaTableColumnService.checkIsExistForeignKeyByColumnIds(ids);
    }

    public void deleteIndexMeta(List<DynaBean> indexs) {

        String resourcetableId =  indexs.get(0).getStr("TABLEINDEX_RESOURCETABLE_ID");
        DynaBean dynaBean = metaService.selectOneByPk("JE_CORE_RESOURCETABLE",resourcetableId);
        List<DynaBean> funcList = metaService.select("JE_CORE_FUNCINFO",ConditionsWrapper.builder().eq("FUNCINFO_TABLENAME",dynaBean.getStr("RESOURCETABLE_TABLECODE")));
        String[] funcIds = new String[funcList.size()];
        if(funcList!=null&&funcList.size()>0){
            for(int i =0;i<funcList.size();i++ ){
                DynaBean func = funcList.get(i);
                funcIds[i]= func.getStr("JE_CORE_FUNCINFO_ID");
            }
        }
        String[] delIds = new String[indexs.size()];
        String[] codes = new String[indexs.size()];
        for (int i = 0; i < indexs.size(); i++) {
            DynaBean tc = indexs.get(i);
            codes[i] = tc.getStr("TABLEINDEX_FIELDCODE");
            delIds[i] = tc.getStr("JE_CORE_TABLEINDEX_ID");
        }
        if(funcIds.length>0){
            metaService.executeSql("UPDATE JE_CORE_RESOURCECOLUMN SET RESOURCECOLUMN_INDEX='0' WHERE RESOURCECOLUMN_CODE IN ({0})  AND RESOURCECOLUMN_FUNCINFO_ID IN ({1})",Arrays.asList(codes),Arrays.asList(funcIds));
        }
        if (delIds.length > 0) {
            //删除JE_CORE_TABLEINDEX的索引
            metaService.executeSql("DELETE FROM JE_CORE_TABLEINDEX WHERE JE_CORE_TABLEINDEX_ID IN ({0})", Arrays.asList(delIds));
        }
    }

    public void deleteKeyMeta(List<DynaBean> keys) {
        String[] delIds = new String[keys.size()];
        for (int i = 0; i < keys.size(); i++) {
            DynaBean tc = keys.get(i);
            delIds[i] = tc.getStr("JE_CORE_TABLEKEY_ID");
        }

        if (delIds.length > 0) {
            metaService.executeSql("DELETE FROM JE_CORE_TABLEKEY WHERE JE_CORE_TABLEKEY_ID IN ({0})", Arrays.asList(delIds));
        }
    }

    /**
     * 级联删除字段获取要删除的键
     *
     * @param columns
     * @return
     */
    public List<DynaBean> getDelKeys(List<DynaBean> columns) {
        List<DynaBean> keys = new ArrayList<>();
        for (DynaBean column : columns) {
            DynaBean key = metaService.selectOne("JE_CORE_TABLEKEY",
                    ConditionsWrapper.builder()
                            .eq("TABLEKEY_RESOURCETABLE_ID", column.getStr("TABLECOLUMN_RESOURCETABLE_ID"))
                            .eq("TABLEKEY_COLUMNCODE", column.getStr("TABLECOLUMN_CODE")));
            if (key != null) {
                keys.add(key);
            }
        }
        for (DynaBean key : keys) {
            metaTableTraceService.saveTableTrace("JE_CORE_TABLEKEY", key, key, "DELETE", key.getStr("TABLEKEY_RESOURCETABLE_ID"), key.getStr("TABLEKEY_ISCREATE"));
        }
        return keys;
    }

    /**
     * 级联删除字段获取要删除的索引
     *
     * @param columns
     * @return
     */
    public List<DynaBean> getDelIndexs(List<DynaBean> columns) {
        List<DynaBean> indexs = new ArrayList<>();
        for (DynaBean column : columns) {
            List<DynaBean> columnIndexs = metaService.select(ConditionsWrapper.builder()
                    .table("JE_CORE_TABLEINDEX")
                    .eq("TABLEINDEX_RESOURCETABLE_ID", column.getStr("TABLECOLUMN_RESOURCETABLE_ID"))
                    .eq("TABLEINDEX_FIELDCODE", column.getStr("TABLECOLUMN_CODE")));
            indexs.addAll(columnIndexs);
        }
        for (DynaBean index : indexs) {
            metaTableTraceService.saveTableTrace("JE_CORE_TABLEINDEX", index, null, "DELETE", index.getStr("TABLEINDEX_RESOURCETABLE_ID"), index.getStr("TABLEINDEX_ISCREATE"));
        }
        return indexs;
    }

    @Override
    public void deleteCascadeViewColumn(String tableCode, List<DynaBean> columns) {
        metaTableColumnService.deleteCascadeViewColumn(tableCode, columns);
    }

    @Override
    public void impNewCols(DynaBean dynaBean) {
        metaTableColumnService.impNewCols(dynaBean);
    }

    @Override
    public String checkColumns(List<DynaBean> columns, Boolean jeCore) {
        return metaTableColumnService.checkColumns(columns, jeCore);
    }

    @Override
    public List<String> requireDeletePhysicalColumnDDL(String tableCode, List<DynaBean> columns) {
        return metaTableColumnService.requireDeletePhysicalColumnDDL(tableCode, columns);
    }

    @Override
    public void deleteColumnMeta(String tableCode, List<DynaBean> columns) {
        metaTableColumnService.deleteColumnMeta(tableCode, columns);
    }

    @Override
    public void deleteColumn(String tableCode, List<DynaBean> columns, Boolean isDdl) {
        metaTableColumnService.deleteColumn(tableCode, columns, isDdl);
    }

    @Override
    public String addColumnByDD(DynaBean dynaBean) {
        return metaTableColumnService.addColumnByDD(dynaBean);
    }

    @Override
    public String addColumnByDDList(DynaBean dynaBean) {
       return metaTableColumnService.addColumnByDDList(dynaBean);
    }

    @Override
    public String addColumnByTable(DynaBean dynaBean) {
        return metaTableColumnService.addColumnByTable(dynaBean);
    }

    @Override
    public Integer addColumnByAtom(String strData, String tableCode, String pkValue) {
        return metaTableColumnService.addColumnByAtom(strData, tableCode, pkValue);
    }

    @Override
    public void addAtomByColumn(String strData, String atomcolumnId) {
        metaTableColumnService.addAtomByColumn(strData, atomcolumnId);
    }

    @Override
    public void initCreateColumns(DynaBean table) throws APIWarnException {
        metaTableColumnService.initCreateColumns(table);
    }

    @Override
    public void initUpdateColumns(DynaBean table) throws APIWarnException {
        metaTableColumnService.initUpdateColumns(table);
    }

    @Override
    public void initShColumns(DynaBean table) {
        metaTableColumnService.initShColumns(table);
    }

    @Override
    public boolean addSystemColumn(HttpServletRequest request) throws APIWarnException {
        return metaTableColumnService.addSystemColumn(request);
    }

    @Override
    public int doUpdateList(DynaBean dynaBean, String strData) {
        return metaTableColumnService.doUpdateList(dynaBean, strData);
    }

    @Override
    public String checkUnique(String ids, String pkValue) {
        return metaTableColumnService.checkUnique(ids, pkValue);
    }

    @Override
    public int doUpdateListByColumn(DynaBean dynaBean, String strData) throws APIWarnException {
        return metaTableColumnService.doUpdateListByColumn(dynaBean, strData);
    }

    @Override
    public List<DynaBean> selectTableByPks(String tableCode, String[] split) {
        return metaTableColumnService.selectTableByPks(tableCode, split);
    }

    @Override
    public Map<String, Object> addFieldToLogicTable(DynaBean dynaBean) {
        return metaTableColumnService.addFieldToLogicTable(dynaBean);
    }

    @Override
    public String addField(DynaBean dynaBean) {
        return metaTableColumnService.addField(dynaBean);
    }

    @Override
    public void initColumns(DynaBean resourceTable, Boolean isTree) {
        metaTableColumnService.initColumns(resourceTable,isTree);
    }

}
